package cn.com.cym.gamezao.service.single.impl;

import cn.com.cym.gamezao.base.*;
import cn.com.cym.gamezao.dto.LostFoundDto;
import cn.com.cym.gamezao.entity.single.LostFound;
import cn.com.cym.gamezao.enums.StatusDesc;
import cn.com.cym.gamezao.exception.BaseException;
import cn.com.cym.gamezao.repository.single.LostFoundRepository;
import cn.com.cym.gamezao.service.single.LostFoundService;
import cn.com.cym.gamezao.util.CommonUtils;
import cn.hutool.core.util.ReflectUtil;
import lombok.SneakyThrows;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

@Service
@Transactional(rollbackFor = Exception.class)
public class LostFoundImpl extends BaseImpl<LostFound> implements LostFoundService {

    final LostFoundRepository thisRepository;

    public LostFoundImpl(LostFoundRepository lostFoundRepository){
        this.thisRepository = lostFoundRepository;
    }

    @Override
    public BaseRepository<LostFound, Long> getJpaRepository() {
        return this.thisRepository;
    }

    @Override
    public Page<LostFound> findByPageable(SearchPage searchPage) {
        //如果排序为空，则默认为按照id排序
        if(searchPage.getSortBy().size()==0){
            List<String> sortBy = searchPage.getSortBy();
            sortBy.add("id");
        }
        String[] sortBy = searchPage.getSortBy().toArray(new String[searchPage.getSortBy().size()]);
        if(searchPage.getCurrent()<1){
            searchPage.setCurrent(1);
        }
        Pageable pageable = PageRequest.of(searchPage.getCurrent()-1, searchPage.getPageSize(), searchPage.getSort(), sortBy);

        Specification<LostFound> specification = new Specification<>() {

            private static final long serialVersionUID = -2661077778894635593L;

            @SneakyThrows
            @Override
            public Predicate toPredicate(Root<LostFound> root,
                                         CriteriaQuery<?> query, CriteriaBuilder cb) {
                final Map<String, Field> fieldMap = ReflectUtil.getFieldMap(LostFound.class);
                return cb.and(CommonUtils.pageSet(fieldMap,searchPage,cb,root));
            }
        };
        //System.out.println(specification);
        return this.thisRepository.findAll(specification, pageable);
    }

    @Override
    public LostFound apply(LostFoundDto lostFoundDto) {
        final LostFound lostFound = this.fetchOne(lostFoundDto.getId());
        if(lostFound == null){
            throw new BaseException("未找到数据",new ResultResponse("未找到数据", HttpStatus.BAD_REQUEST.value()));
        }
        if(null != lostFound.getLostOwnerName()){
            throw new BaseException("该物品已被认领，请联系客服",new ResultResponse("该物品已被认领，请联系客服", HttpStatus.BAD_REQUEST.value()));
        }
        lostFound.setLostOwnerName(lostFoundDto.getLostOwnerName());
        lostFound.setTel(lostFoundDto.getTel());
        lostFound.setStatusDesc(StatusDesc.APPLY.name());
        this.save(lostFound);
        return lostFound;
    }

    @Override
    public LostFound audit(AuditRequest auditRequest) {
        final LostFound lostFound = this.fetchOne(auditRequest.getId());
        if(lostFound == null){
            throw new BaseException("未找到数据",new ResultResponse("未找到数据", HttpStatus.BAD_REQUEST.value()));
        }
        if(auditRequest.getStatusDesc().equals(StatusDesc.END)){
            lostFound.setClaim(true);
        }
        lostFound.setStatusDesc(auditRequest.getStatusDesc().name());
        this.save(lostFound);
        return lostFound;
    }

}
